<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <title>Flex布局教学演示</title>
    <style>
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
      }

      body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        line-height: 1.6;
        color: #333;
        background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
        padding: 20px;
        min-height: 100vh;
      }

      header {
        text-align: center;
        margin-bottom: 40px;
        padding: 30px;
        background: white;
        border-radius: 10px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
      }

      h1 {
        color: #2c3e50;
        margin-bottom: 15px;
      }

      .intro {
        max-width: 800px;
        margin: 0 auto;
        color: #7f8c8d;
      }

      .main-content {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 30px;
        max-width: 1200px;
        margin: 0 auto;
      }

      @media (max-width: 900px) {
        .main-content {
          grid-template-columns: 1fr;
        }
      }

      .demo-section {
        background: white;
        border-radius: 10px;
        padding: 25px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
      }

      .demo-container {
        height: 300px;
        border: 2px solid #3498db;
        border-radius: 5px;
        margin: 20px 0;
        padding: 15px;
        background: #ecf0f1;
        overflow: auto;
        display: flex;
        position: relative;
      }

      .axis {
        position: absolute;
        pointer-events: none;
        z-index: 1;
      }

      .main-axis {
        top: 50%;
        left: 0;
        right: 0;
        height: 1px;
        background: linear-gradient(
          to right,
          transparent,
          #e74c3c,
          transparent
        );
      }

      .cross-axis {
        top: 0;
        bottom: 0;
        left: 50%;
        width: 1px;
        background: linear-gradient(
          to bottom,
          transparent,
          #2ecc71,
          transparent
        );
      }

      .axis-label {
        position: absolute;
        font-size: 12px;
        font-weight: bold;
        padding: 3px 6px;
        border-radius: 3px;
        color: white;
      }

      .main-axis-label {
        background: #e74c3c;
        top: 50%;
        right: 10px;
        transform: translateY(-50%);
      }

      .cross-axis-label {
        background: #2ecc71;
        left: 50%;
        bottom: 10px;
        transform: translateX(-50%);
      }

      .demo-item {
        min-width: 80px;
        height: 60px;
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-weight: bold;
        border-radius: 5px;
        margin: 5px;
        transition: all 0.3s ease;
      }

      .item-1 {
        background: #3498db;
      }
      .item-2 {
        background: #2ecc71;
      }
      .item-3 {
        background: #e74c3c;
      }
      .item-4 {
        background: #f39c12;
      }
      .item-5 {
        background: #9b59b6;
      }
      .item-6 {
        background: #1abc9c;
      }

      .controls {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 15px;
        margin: 20px 0;
      }

      .control-group {
        margin-bottom: 15px;
      }

      .control-group h3 {
        margin-bottom: 10px;
        color: #2c3e50;
        font-size: 1.1em;
      }

      .btn {
        padding: 10px 15px;
        border: none;
        border-radius: 5px;
        background: #3498db;
        color: white;
        cursor: pointer;
        transition: all 0.3s ease;
        width: 100%;
        text-align: left;
        margin-bottom: 8px;
      }

      .btn:hover {
        background: #2980b9;
        transform: translateY(-2px);
      }

      .btn-active {
        background: #16a085;
        box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
      }

      .slider-container {
        margin-bottom: 15px;
      }

      .slider-container label {
        display: block;
        margin-bottom: 5px;
        font-weight: bold;
        color: #2c3e50;
      }

      .slider {
        width: 100%;
        margin: 10px 0;
      }

      .code-container {
        background: #2c3e50;
        color: white;
        padding: 15px;
        border-radius: 5px;
        font-family: monospace;
        overflow: auto;
        margin: 20px 0;
      }

      .code-container pre {
        margin: 0;
      }

      .property {
        color: #3498db;
      }

      .value {
        color: #2ecc71;
      }

      .comment {
        color: #95a5a6;
      }

      .explanation {
        background: #f8f9fa;
        padding: 20px;
        border-radius: 5px;
        border-left: 4px solid #3498db;
      }

      .explanation h2 {
        color: #2c3e50;
        margin-bottom: 15px;
      }

      .explanation p {
        margin-bottom: 15px;
      }

      .highlight {
        background: yellow;
        padding: 2px 5px;
        border-radius: 3px;
      }

      .info-box {
        background: #d1ecf1;
        border-left: 4px solid #0c5460;
        padding: 15px;
        margin: 20px 0;
        border-radius: 5px;
      }

      .example-grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 15px;
        margin: 20px 0;
      }

      .example-btn {
        padding: 12px;
        border: none;
        border-radius: 5px;
        background: #95a5a6;
        color: white;
        cursor: pointer;
        transition: all 0.3s ease;
        text-align: center;
      }

      .example-btn:hover {
        background: #7f8c8d;
        transform: translateY(-2px);
      }

      footer {
        text-align: center;
        margin-top: 50px;
        padding: 20px;
        color: #7f8c8d;
      }

      .item-controls {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        margin: 15px 0;
      }

      .item-btn {
        padding: 8px 12px;
        border: none;
        border-radius: 5px;
        background: #95a5a6;
        color: white;
        cursor: pointer;
        transition: all 0.3s ease;
      }

      .item-btn:hover {
        background: #7f8c8d;
      }

      .flex-cheatsheet {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 10px;
        margin: 20px 0;
      }

      .cheatsheet-item {
        background: #f8f9fa;
        padding: 10px;
        border-radius: 5px;
        border: 1px solid #ddd;
      }

      .cheatsheet-item h4 {
        margin-bottom: 5px;
        color: #2c3e50;
      }

      .cheatsheet-item p {
        font-size: 0.9em;
        color: #7f8c8d;
      }
    </style>
  </head>
  <body>
    <header>
      <h1>Flex布局教学演示</h1>
      <p class="intro">
        这个页面通过交互式演示帮助理解Flexbox布局模型，Flexbox是CSS3中强大的布局模式。
      </p>
    </header>

    <div class="main-content">
      <div class="demo-section">
        <h3>Flex布局属性</h3>

        <div class="info-box">
          <p>
            Flex布局由<strong>Flex容器</strong>（父元素）和<strong>Flex项目</strong>（子元素）组成。
          </p>
          <p>使用下面的控件修改Flex属性，观察布局的变化。</p>
        </div>

        <div class="controls">
          <div class="control-group">
            <h3>主轴方向 (flex-direction)</h3>
            <button
              class="btn"
              onclick="setFlexDirection('row')"
            >
              row (行)
            </button>
            <button
              class="btn"
              onclick="setFlexDirection('row-reverse')"
            >
              row-reverse (行反向)
            </button>
            <button
              class="btn"
              onclick="setFlexDirection('column')"
            >
              column (列)
            </button>
            <button
              class="btn"
              onclick="setFlexDirection('column-reverse')"
            >
              column-reverse (列反向)
            </button>
          </div>

          <div class="control-group">
            <h3>主轴对齐 (justify-content)</h3>
            <button
              class="btn"
              onclick="setJustifyContent('flex-start')"
            >
              flex-start (起始处)
            </button>
            <button
              class="btn"
              onclick="setJustifyContent('flex-end')"
            >
              flex-end (末尾处)
            </button>
            <button
              class="btn"
              onclick="setJustifyContent('center')"
            >
              center (居中)
            </button>
            <button
              class="btn"
              onclick="setJustifyContent('space-between')"
            >
              space-between (两端对齐)
            </button>
            <button
              class="btn"
              onclick="setJustifyContent('space-around')"
            >
              space-around (周围间隔)
            </button>
            <button
              class="btn"
              onclick="setJustifyContent('space-evenly')"
            >
              space-evenly (均匀间隔)
            </button>
          </div>

          <div class="control-group">
            <h3>交叉轴对齐 (align-items)</h3>
            <button
              class="btn"
              onclick="setAlignItems('stretch')"
            >
              stretch (拉伸)
            </button>
            <button
              class="btn"
              onclick="setAlignItems('flex-start')"
            >
              flex-start (起始处)
            </button>
            <button
              class="btn"
              onclick="setAlignItems('flex-end')"
            >
              flex-end (末尾处)
            </button>
            <button
              class="btn"
              onclick="setAlignItems('center')"
            >
              center (居中)
            </button>
            <button
              class="btn"
              onclick="setAlignItems('baseline')"
            >
              baseline (基线)
            </button>
          </div>

          <div class="control-group">
            <h3>多行对齐 (align-content)</h3>
            <button
              class="btn"
              onclick="setAlignContent('stretch')"
            >
              stretch (拉伸)
            </button>
            <button
              class="btn"
              onclick="setAlignContent('flex-start')"
            >
              flex-start (起始处)
            </button>
            <button
              class="btn"
              onclick="setAlignContent('flex-end')"
            >
              flex-end (末尾处)
            </button>
            <button
              class="btn"
              onclick="setAlignContent('center')"
            >
              center (居中)
            </button>
            <button
              class="btn"
              onclick="setAlignContent('space-between')"
            >
              space-between (两端对齐)
            </button>
            <button
              class="btn"
              onclick="setAlignContent('space-around')"
            >
              space-around (周围间隔)
            </button>
          </div>

        </div>

        <h3>Flex容器属性</h3>
        <div class="flex-cheatsheet">
          <div class="cheatsheet-item">
            <h4>flex-direction</h4>
            <p>定义主轴方向：row | row-reverse | column | column-reverse</p>
          </div>
          <div class="cheatsheet-item">
            <h4>justify-content</h4>
            <p>
              主轴对齐方式：flex-start | flex-end | center | space-between |
              space-around | space-evenly
            </p>
          </div>
          <div class="cheatsheet-item">
            <h4>align-items</h4>
            <p>
              交叉轴对齐方式：stretch | flex-start | flex-end | center |
              baseline
            </p>
          </div>
          <div class="cheatsheet-item">
            <h4>align-content</h4>
            <p>
              多行对齐方式：stretch | flex-start | flex-end | center |
              space-between | space-around
            </p>
          </div>
          <div class="cheatsheet-item">
            <h4>flex-wrap</h4>
            <p>换行方式：nowrap | wrap | wrap-reverse</p>
          </div>
          <div class="cheatsheet-item">
            <h4>gap</h4>
            <p>项目之间的间隔：长度值</p>
          </div>
        </div>

        <h3>Flex项目属性</h3>
        <div class="flex-cheatsheet">
          <div class="cheatsheet-item">
            <h4>order</h4>
            <p>项目排序：数值（默认0）</p>
          </div>
          <div class="cheatsheet-item">
            <h4>flex-grow</h4>
            <p>放大比例：数值（默认0）</p>
          </div>
          <div class="cheatsheet-item">
            <h4>flex-shrink</h4>
            <p>缩小比例：数值（默认1）</p>
          </div>
          <div class="cheatsheet-item">
            <h4>flex-basis</h4>
            <p>项目初始大小：长度值 | auto</p>
          </div>
          <div class="cheatsheet-item">
            <h4>align-self</h4>
            <p>
              单个项目对齐方式：auto | flex-start | flex-end | center | baseline
              | stretch
            </p>
          </div>
        </div>
        
      </div>

      

      <div class="explanation">
        <h2>Flexbox布局演示</h2>

        <div class="item-controls">
            <button
              class="item-btn"
              style="background-color: red;"
              onclick="toggleWrap()"
            >
              切换换行
            </button>
            <button
              class="item-btn"
              onclick="addItem()"
            >
              添加项目
            </button>
            <button
              class="item-btn"
              onclick="removeItem()"
            >
              移除项目
            </button>
            <button
              class="item-btn"
              onclick="resetDemo()"
            >
              重置演示
            </button>
          </div>
  
          <div class="example-grid">
            <button
              class="example-btn"
              onclick="applyExample('navbar')"
            >
              导航栏示例
            </button>
            <button
              class="example-btn"
              onclick="applyExample('cardGrid')"
            >
              卡片网格示例
            </button>
            <button
              class="example-btn"
              onclick="applyExample('centering')"
            >
              居中布局示例
            </button>
            <button
              class="example-btn"
              onclick="applyExample('stickyFooter')"
            >
              粘性页脚示例
            </button>
          </div>

        <div
          class="demo-container"
          id="demoContainer"
        >
          <div class="axis main-axis"></div>
          <div class="axis cross-axis"></div>
          <div class="axis-label main-axis-label">主轴</div>
          <div class="axis-label cross-axis-label">交叉轴</div>

          <div class="demo-item item-1">项目 1</div>
          <div class="demo-item item-2">项目 2</div>
          <div class="demo-item item-3">项目 3</div>
          <div class="demo-item item-4">项目 4</div>
        </div>

        <div class="slider-container">
            <label for="gapSlider"
              >项目间隔 (gap): <span id="gapValue">0px</span></label
            >
            <input
              type="range"
              id="gapSlider"
              class="slider"
              min="0"
              max="30"
              value="0"
              oninput="setGap(this.value)"
            />
          </div>
  

        <div class="code-container">
          <pre id="cssCode">.container {
  <span class="property">display</span>: <span class="value">flex</span>;
  <span class="property">flex-direction</span>: <span class="value">row</span>;
  <span class="property">justify-content</span>: <span class="value">flex-start</span>;
  <span class="property">align-items</span>: <span class="value">stretch</span>;
  <span class="property">flex-wrap</span>: <span class="value">nowrap</span>;
  <span class="property">gap</span>: <span class="value">0px</span>;
}</pre>
        </div>

        <h3>Flexbox轴线</h3>
        <p>Flexbox布局基于两条轴线：</p>
        <ul>
          <li>
            <strong>主轴 (Main Axis)</strong> - 由 flex-direction 定义的方向
          </li>
          <li><strong>交叉轴 (Cross Axis)</strong> - 垂直于主轴的方向</li>
        </ul>

        <div class="info-box">
          <p>
            <strong>提示：</strong>
            在左侧演示区域尝试不同的Flex属性，观察布局如何变化。红色线表示主轴，绿色线表示交叉轴。
          </p>
        </div>
      </div>
    </div>

    <footer>
      <p>[羽神同行]CSS陪跑训练营 &copy; EOVA.CN</p>
    </footer>

    <script>
      // 获取演示容器和代码显示元素
      const demoContainer = document.getElementById('demoContainer')
      const cssCode = document.getElementById('cssCode')
      const gapValue = document.getElementById('gapValue')
      let isWrapped = false
      let itemCount = 4

      // 设置flex-direction
      function setFlexDirection(value) {
        demoContainer.style.flexDirection = value
        updateCode('flex-direction', value)
        updateButtonStates('flex-direction', value)
      }

      // 设置justify-content
      function setJustifyContent(value) {
        demoContainer.style.justifyContent = value
        updateCode('justify-content', value)
        updateButtonStates('justify-content', value)
      }

      // 设置align-items
      function setAlignItems(value) {
        demoContainer.style.alignItems = value
        updateCode('align-items', value)
        updateButtonStates('align-items', value)
      }

      // 设置align-content
      function setAlignContent(value) {
        demoContainer.style.alignContent = value
        updateCode('align-content', value)
        updateButtonStates('align-content', value)
      }

      // 设置间隔
      function setGap(value) {
        demoContainer.style.gap = value + 'px'
        gapValue.textContent = value + 'px'
        updateCode('gap', value + 'px')
      }

      // 切换换行
      function toggleWrap() {
        isWrapped = !isWrapped
        demoContainer.style.flexWrap = isWrapped ? 'wrap' : 'nowrap'
        updateCode('flex-wrap', isWrapped ? 'wrap' : 'nowrap')
      }

      // 添加项目
      function addItem() {
        if (itemCount >= 8) return

        itemCount++
        const newItem = document.createElement('div')
        newItem.className = `demo-item item-${itemCount % 6 || 6}`
        newItem.textContent = `项目 ${itemCount}`

        demoContainer.appendChild(newItem)
      }

      // 移除项目
      function removeItem() {
        if (itemCount <= 1) return

        const lastItem = demoContainer.lastElementChild
        if (lastItem && lastItem.classList.contains('demo-item')) {
          demoContainer.removeChild(lastItem)
          itemCount--
        }
      }

      // 重置演示
      function resetDemo() {
        demoContainer.style.flexDirection = 'row'
        demoContainer.style.justifyContent = 'flex-start'
        demoContainer.style.alignItems = 'stretch'
        demoContainer.style.alignContent = 'stretch'
        demoContainer.style.flexWrap = 'nowrap'
        demoContainer.style.gap = '0px'

        gapValue.textContent = '0px'
        document.getElementById('gapSlider').value = 0

        isWrapped = false

        // 移除额外项目
        const items = demoContainer.querySelectorAll('.demo-item')
        if (items.length > 4) {
          for (let i = 4; i < items.length; i++) {
            demoContainer.removeChild(items[i])
          }
        }

        itemCount = 4

        updateCode('reset')
        updateButtonStates('reset')
      }

      // 应用示例布局
      function applyExample(example) {
        switch (example) {
          case 'navbar':
            setFlexDirection('row')
            setJustifyContent('space-between')
            setAlignItems('center')
            demoContainer.style.flexWrap = 'nowrap'
            break

          case 'cardGrid':
            setFlexDirection('row')
            setJustifyContent('space-around')
            setAlignItems('stretch')
            demoContainer.style.flexWrap = 'wrap'
            setGap(15)
            document.getElementById('gapSlider').value = 15
            break

          case 'centering':
            setFlexDirection('row')
            setJustifyContent('center')
            setAlignItems('center')
            demoContainer.style.flexWrap = 'nowrap'
            break

          case 'stickyFooter':
            setFlexDirection('column')
            setJustifyContent('space-between')
            setAlignItems('stretch')
            demoContainer.style.flexWrap = 'nowrap'
            break
        }

        updateCode('all')
      }

      // 更新代码显示
      function updateCode(property, value) {
        const code = cssCode.innerHTML

        if (property === 'reset') {
          cssCode.innerHTML = `.container {
  <span class="property">display</span>: <span class="value">flex</span>;
  <span class="property">flex-direction</span>: <span class="value">row</span>;
  <span class="property">justify-content</span>: <span class="value">flex-start</span>;
  <span class="property">align-items</span>: <span class="value">stretch</span>;
  <span class="property">flex-wrap</span>: <span class="value">nowrap</span>;
  <span class="property">gap</span>: <span class="value">0px</span>;
}`
          return
        }

        if (property === 'all') {
          cssCode.innerHTML = `.container {
  <span class="property">display</span>: <span class="value">flex</span>;
  <span class="property">flex-direction</span>: <span class="value">${
    demoContainer.style.flexDirection || 'row'
  }</span>;
  <span class="property">justify-content</span>: <span class="value">${
    demoContainer.style.justifyContent || 'flex-start'
  }</span>;
  <span class="property">align-items</span>: <span class="value">${
    demoContainer.style.alignItems || 'stretch'
  }</span>;
  <span class="property">flex-wrap</span>: <span class="value">${
    demoContainer.style.flexWrap || 'nowrap'
  }</span>;
  <span class="property">gap</span>: <span class="value">${
    demoContainer.style.gap || '0px'
  }</span>;
}`
          return
        }

        const newCode = code.replace(
          new RegExp(
            `<span class="property">${property}</span>: <span class="value">[^<]+</span>`,
          ),
          `<span class="property">${property}</span>: <span class="value">${value}</span>`,
        )

        cssCode.innerHTML = newCode
      }

      // 更新按钮状态
      function updateButtonStates(type, value) {
        const buttons = document.querySelectorAll('.btn')

        // 重置所有按钮状态
        buttons.forEach((button) => {
          button.classList.remove('btn-active')
        })

        if (type === 'reset') {
          return
        }

        // 激活当前按钮
        const activeButton = Array.from(buttons).find(
          (button) =>
            button.textContent.includes(value) ||
            (type === 'flex-direction' &&
              button.onclick &&
              button.onclick.toString().includes(value)) ||
            (type === 'justify-content' &&
              button.onclick &&
              button.onclick.toString().includes(value)) ||
            (type === 'align-items' &&
              button.onclick &&
              button.onclick.toString().includes(value)) ||
            (type === 'align-content' &&
              button.onclick &&
              button.onclick.toString().includes(value)),
        )

        if (activeButton) {
          activeButton.classList.add('btn-active')
        }
      }

      // 初始化
      window.onload = function () {
        updateButtonStates('flex-direction', 'row')
        updateButtonStates('justify-content', 'flex-start')
        updateButtonStates('align-items', 'stretch')
        updateButtonStates('align-content', 'stretch')
      }
    </script>
  </body>
</html>
